package cc.autoapi.pucong.auto.flow.core.flow.execNode.task;


import cc.autoapi.pucong.auto.flow.core.flow.execNode.exception.AutoDesignException;
import cc.autoapi.pucong.auto.flow.core.flow.execNode.selfenum.NodeTypeEnum;
import cc.autoapi.pucong.auto.flow.core.flow.execNode.task.extend.AbstractExtendTask;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @description:
 * @author: cong.pu
 * @create: 2024-09-25 16:32
 **/
@Slf4j
public class TaskFactory {
    private static Map<String, Class<? extends AbstractExtendTask>> taskMap = new HashMap<>(16);

    public static Set<String> getTaskMapKey() {
        return taskMap.keySet();
    }

    public static void registerTask(String taskCode, Class<? extends AbstractExtendTask> task) {
        if (taskMap.containsKey(taskCode)) {
            throw new AutoDesignException("任务编码已存在，请检查任务类型是否重复注册");
        }
        if (NodeTypeEnum.getItemByValue(taskCode) != null) {
            throw new AutoDesignException("任务编码和内置组件重复，请重新定义任务类型");
        }
        taskMap.put(taskCode, task);
    }

    public static <T extends AbstractTask> T getTask(NodeTypeEnum nodeType) {
        T t = null;
        try {
            t = (T) Class.forName(nodeType.getTaskClass().getName()).newInstance();
        } catch (Exception e) {
            log.error("获取任务类型失败", e);
            throw new AutoDesignException("获取任务类型失败");
        }
        return t;
    }

    public static <T extends AbstractTask> T getTask(String taskCode) {
        NodeTypeEnum itemByValue = NodeTypeEnum.getItemByValue(taskCode);
        if (itemByValue != null) {
            return getTask(itemByValue);
        }
        Class<? extends AbstractExtendTask> aClass = taskMap.get(taskCode);
        if (aClass == null) {
            throw new AutoDesignException("任务类型不存在，找不到任务类");
        }
        T t = null;
        try {
            t = (T) aClass.newInstance();
        } catch (Exception e) {
            throw new AutoDesignException("获取任务类型失败");
        }
        return t;
    }
}
